package org.zhuzx.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * 可以进行元素团操作的扩展型链表
 * @author	zhuzx	2016年1月19日
 */
@Deprecated//改成HashSet
public class LinkedGroupList<E> extends LinkedList<E> {
	private static final long serialVersionUID = -7703914836630348641L;
	
	private Map<E, RingNode<E>> groups = new HashMap<E, RingNode<E>>();
	
	/**
	 * 添加一个元素团，在添加这些元素之余对元素彼此间进行了绑定。<br>
	 * 随后使用removeGroup方法移除其中任意一个元素时，将会移除这个元素团的全部元素。
	 */
	@SuppressWarnings("unchecked")
	public void addGroup(E... group) {
		int num = group.length;
		RingNode<E> lastNode = new RingNode<E>(group[num-1], null);
		RingNode<E> prevNode = lastNode;
		for (int i = num-2; i>=0; i--) {
			prevNode = new RingNode<E>(group[i], prevNode);
			groups.put(group[i], prevNode);
			super.add(group[num-2-i]);
		}
		lastNode.next = prevNode;
		groups.put(group[num-1], lastNode);
		super.add(group[num-1]);
	}
	
	/**
	 * 移除这个元素所在的元素团中所有元素。
	 */
	public boolean removeGroup(Object o) {
		RingNode<E> node = groups.get(o);
		RingNode<E> temp = null;
		boolean contained = false;
		while (node != null) {
			contained = super.remove(node.item) || contained;
			groups.remove(node.item);
			temp = node;
			node = node.next;
			temp.next = null;
			temp.item = null;
		}
		return contained;
	}
	
	/*这两个方法与上面两个方法的功能完全相同，但性能略差。
	@SuppressWarnings("unchecked")
	public void addGroup(E... group) {
		for (E e : group) {
			super.add(e);
		}
		createRing(group);
	}
	
	public boolean removeGroup(Object o) {
		List<E> ringItems = destroyRing(groups.get(o));
		boolean contained = false;
		for (E e : ringItems) {
			contained = super.remove(e) || contained;
		}
		return contained;
	}
	*/
	
	public void createRing(E[] group) {
		RingNode<E> lastNode = new RingNode<E>(group[group.length-1], null);
		RingNode<E> prevNode = lastNode;
		for (int i = group.length-2; i>=0; i--) {
			prevNode = new RingNode<E>(group[i], prevNode);
			groups.put(group[i], prevNode);
		}
		lastNode.next = prevNode;
		groups.put(group[group.length-1], lastNode);
	}
	
	public List<E> destroyRing(RingNode<E> node) {
		RingNode<E> temp = null;
		List<E> ringItems = new ArrayList<E>();
		while (node != null) {
			ringItems.add(node.item);
			groups.remove(node.item);
			temp = node;
			node = node.next;
			temp.next = null;
			temp.item = null;
		}
		return ringItems;
	}
	
	private static class RingNode<E> {
		E item;
		RingNode<E> next;
		
		RingNode(E element, RingNode<E> next) {
			this.item = element;
			this.next = next;
		}
	}
	
}
